/*
 * Copyright @ 2015 Goldpac Co. Ltd. All right reserved.
 * 
 * @fileName GetICDataAction.java
 * 
 * @author rui.kang
 */
package com.goldpac.cardbiz.service.action;

import java.util.ArrayList;
import java.util.List;

import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.goldpac.cardbiz.common.Global;
import com.goldpac.cardbiz.error.Errors;
import com.goldpac.cardbiz.model.base.Param;
import com.goldpac.cardbiz.model.dto.ICData;
import com.goldpac.cardbiz.model.dto.PersoDatas;
import com.goldpac.cardbiz.model.dto.PersoRecordDto;
import com.goldpac.cardbiz.model.dto.PrintWriteData;
import com.goldpac.cardbiz.model.dto.SummaryFieldsData;
import com.goldpac.cardbiz.plugins.FileTouch;
import com.goldpac.cardbiz.server.session.entity.GetICDataRequest;
import com.goldpac.cardbiz.server.session.entity.GetICDataResponse;
import com.goldpac.cardbiz.server.session.socket.Action;
import com.goldpac.cardbiz.server.session.socket.SocketPacket;
import com.goldpac.cardbiz.service.IParamService;
import com.goldpac.cardbiz.service.IPersoRecordService;
import com.goldpac.cardbiz.service.factory.ServiceManager;
import com.goldpac.cardbiz.service.impl.ParamServiceImpl;
import com.goldpac.cardbiz.service.impl.PersoRecordServiceImpl;
import com.goldpac.cardbiz.service.server.JRKCardServer;
import com.goldpac.cardbiz.socket.SketClient;
import com.goldpac.cardbiz.utils.Base64Utils;
import com.goldpac.cardbiz.utils.CryptionUtil;
import com.goldpac.cardbiz.utils.FileUtil;
import com.goldpac.cardbiz.utils.ZipUtil;

import spc.webos.endpoint.ESB2;

/**
 * 从IC卡系统获取数据
 *
 * @ClassName: GetICDataAction
 * @author rui.kang
 * @version 1.0<br />
 * @Date 2017年5月17日 上午9:12:07<br />
 * @Logs <br />
 *       ****************************************************<br />
 */
public class GetICDataAction implements Action {

    private Logger log = LoggerFactory.getLogger(GetICDataAction.class);
    private Logger logger = LoggerFactory.getLogger("application0017");
    /*public GetICDataAction() throws Exception {
    	// ESB2 跟MQ创建连接 exe
    	esb2.setAsynResponseOnMessage(new AsynResponseOnMessage()); // 设置异步应答处理函数 请求方的异步应答  实现业务逻辑处理
    	esb2.init("esb.properties");
    }*/

    @Override
    public void handle(IoSession session, SocketPacket packet) throws Exception {

        PersoRecordDto dto = new PersoRecordDto();
        GetICDataResponse resp = new GetICDataResponse();
        FileTouch ft = new FileTouch();
        Errors errors = new Errors();
        try {
            logger.info("开始获取ESB实例");
            ESB2 esb2 = ServiceManager.getManager().getEsb2();
            // 从数据库中查询，是否存存当前证件号数据
            IPersoRecordService persoRecordService =
                ServiceManager.getManager().getBean("persoRecordServiceImpl", PersoRecordServiceImpl.class);
            GetICDataRequest req = new GetICDataRequest(packet.getBody());

            // dto = persoRecordService.findByIdNo(req.getIdtfno() , null , req.getCardpr());
            // 如果数据库中存在失败状态、初始化状态，则先用本地数据库中数据，否则调用ESB0017交易获取数据。
            logger.info("--->先查找本地数据库中是否存在本卡号" + req.getJrno() + "未制卡数据");
            dto = persoRecordService.findByCardNo(req.getJrno(), Global.PERSO_CODE_FAIL);
            if (dto == null) {
                logger.info("--->先查找本地数据库中是否存在本卡号" + req.getJrno() + "未制卡数据");
                dto = persoRecordService.findByCardNo(req.getJrno(), Global.PERSO_CODE_INIT);
            }
            if (dto == null) {
                logger.info("--->先查找本地数据库中是否存在本卡号" + req.getJrno() + "未结束数据");
                dto = persoRecordService.findByCardNo(req.getJrno(), Global.PERSO_CODE_IC_SUCCESS);
                if (dto != null) {
                    logger.warn("--->当前数据写芯片成功,但卡面打印失败，请联系网点主管销毁此张卡片，并请主管使用【异常卡处理】->【数据重置】功能恢复数据重新制卡。");
                    resp.setErorcd("9999");
                    resp.setErortx("当前数据写芯片成功,但卡面打印失败，请联系网点主管销毁此张卡片，并请主管使用【异常卡处理】->【数据重置】功能恢复数据重新制卡。");
                    resp.setOriginalJson("");
                    packet.setBody(resp.toString());
                    session.write(packet.toString());
                    return;
                }
            }
            if (dto != null) {
                logger.info("--->本地数据库中存在本卡号" + req.getJrno() + "未结束数据");
                resp.setOriginalJson(JSON.toJSONString(dto));
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            dto = persoRecordService.findByIdNo(req.getIdtfno(), Global.PERSO_CODE_PRINTING, req.getCardpr());
            // 如果制卡状态为制卡中
            if (dto != null) {
                logger.warn("--->当前数据制卡状态为【制卡中】,如需重新制卡，请使用【数据重置】功能。");
                resp.setErorcd("9999");
                resp.setErortx("当前数据制卡状态为【制卡中】,如需重新制卡，请使用【数据重置】功能。");
                resp.setOriginalJson("");
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }

            // 1.从IC卡系统获取数据批次号
            JRKCardServer jrkCardServer = new JRKCardServer();
            errors = new Errors();

            String jrno = req.getJrno();// 起始卡号
            String endjrno = req.getEndJrno();// 终止卡号
            String idtfno = req.getIdtfno();// 身份证号
            String idtftp = req.getIdtftp();// 证件类型
            String custna = req.getCustna();// 姓名
            String branchCodeAndTeller = req.getBranchCode();// 包含机构号和柜员号，以逗号分隔
            String arr[] = branchCodeAndTeller.split(",");

            logger.info("起始卡号--->" + jrno);
            logger.info("终止卡号--->" + endjrno);
            logger.info("机构号和柜员号，以逗号分隔--->" + branchCodeAndTeller);
            if (arr.length < 2) {
                logger.warn("机构号或柜员号为空，请在管理平台将信息添加完整");
                resp.setErorcd("9999");
                resp.setErortx("机构信息或柜员号有误，请确认");
                resp.setOriginalJson(JSON.toJSONString(dto));
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;

            }
            String branchCode = branchCodeAndTeller.split(",")[0];
            String teller = branchCodeAndTeller.split(",")[1];
            String isSingleCard = "";
            String count = "";
            String jrnoLast3 = jrno.substring(jrno.length() - 4, jrno.length() - 1);// 末四位的前三位
            String endjrnoLast3 = endjrno.substring(endjrno.length() - 4, endjrno.length() - 1);// 末四位的前三位
            if (jrno.equals(endjrno)) {
                isSingleCard = "0";// 0-是 1-否
                count = "1";
                logger.info("单张制卡");
            } else {
                isSingleCard = "1";// 0-是 1-否
                int ct = Integer.parseInt(endjrnoLast3) - Integer.parseInt(jrnoLast3);
                count = String.valueOf(ct + 1);
                logger.info("多张制卡，数量：" + count + "张");
            }

            // System.out.println(jrno);
            // esb2,是否单张，数量，起始卡号，终止卡号，证件号码，证件类型，姓名，网点机构号，柜员号
            String returnData = jrkCardServer.send0017Andrecv(esb2, isSingleCard, count, jrno, endjrno, idtfno, idtftp,
                custna, branchCode, teller);
            if (returnData.length() < 100) {
                logger.error("ESB返回报文有误--->" + returnData);
                resp.setErorcd("9999");
                if (",,,".equals(returnData)) {
                    resp.setErortx("系统错误");
                } else {
                    resp.setErortx(returnData);
                }
                resp.setOriginalJson(JSON.toJSONString(dto));
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            // String returnData =
            // jrkCardServer.send0017Andrecv(esb2,"0","1","622991100714634128","622991100714634128");
            String cbsData = "";
            String icData = "";
            String cbsFile = "";// 词条数据路径
                                // /icappdata/fts/sndsplace/QIS/20171213/zhka_dfk_11109201_1600799999_20220502_37_002.txt
            String icFile = "";// IC数据路径
                               // /icappdata/fts/sndsplace/QIS/20171213/zhka_dfk_11109201_1600799999_20220502_37_002.zip

            // 新0017接口响应参数 20221101
            String digest = "";// 摘要字段
            String encryptFlag = "";// 加密标识符
            String digestFlag = "";// 摘要标识符
            // 2023/10/23 modify by wen-jie.yin
            String cardSeqNo = "";// 卡序号
            errors = new Errors();

            /*
                            序号     说明           长度
            0 	卡号后四位	4
            1	CVN2	3
            2	磁条卡号	19
            3	联社码	3
            4	制卡年月	7
            5	二磁道	37
            6	三磁道	104
            7	客户英文名	26
            8	卡产品编号	10
            9	失效日期	5
            10	IC卡号	19
            11	磁条卡号	19
            12	卡序号	3
            13	客户中文名	32
            14	客户英文名	32
            15	证件类型	2
            16	证件号码	64
            17	应用生效日期	8
            18	服务码	4
            19	磁条2等效数据	96
            20	脱机PIN	32
            21	有效日期	8
            22	申请日期	8
            23	申请机构	12
            */
            // PersoDatas datas = ft.analysis2(icData, errors);
            String[] Data2 = returnData.split(",");
            if (Data2[0] == null || "".equals(Data2[0]) || Data2[1] == null || "".equals(Data2[1]) || Data2[2] == null
                || "".equals(Data2[2]) || Data2[3] == null || "".equals(Data2[3])) {
                logger.error("ESB返回报文有空值，cbsData--->" + Data2[0]);
                logger.error("ESB返回报文有空值，icData--->" + Data2[1]);
                logger.error("ESB返回报文有空值，cbsFile--->" + Data2[2]);
                logger.error("ESB返回报文有空值，icFile--->" + Data2[3]);
                resp.setErorcd("9999");
                resp.setErortx("数据返回有误！");
                resp.setOriginalJson(JSON.toJSONString(dto));
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            if (!",,,".equals(returnData)) {
                cbsData = Data2[0];
                cbsFile = Data2[2];
                icFile = Data2[3];
                digest = Data2[4];
                encryptFlag = Data2[5];
                digestFlag = Data2[6];
                // 修改从cbsData获取
                cardSeqNo = cbsData.split("\\|")[12];
                IParamService paramService =
                    ServiceManager.getManager().getBean("paramServiceImpl", ParamServiceImpl.class);
                String encrypt_key = paramService.get("PKey", "encrypt_key").getPValue();
                String encryKeyName = paramService.get("PKey", "encrypt_key").getPValue();// digest_flag是否验证摘要的控制参数
                // 调用E180验证摘要20221101
                String need_summay = paramService.get("PKey", "digest_flag").getPValue();// digest_flag是否验证摘要的控制参数
                String digestKeyName = paramService.get("PKey", "digest_key").getPValue();// digest_flag是否验证摘要的控制参数
                SketClient sClient = new SketClient();

                if ("1".equals(need_summay)) {
                    if (!checkDigestByE180(digest, encryptFlag, digestFlag, encryKeyName, digestKeyName, resp, packet,
                        session, sClient, dto))
                        return;
                }

                List<PrintWriteData> printWriteDataList = new ArrayList<PrintWriteData>(); // 磁条及印写数据集合
                PrintWriteData pwd = new PrintWriteData();

                List<SummaryFieldsData> summaryFieldsDataList = new ArrayList<SummaryFieldsData>();// 摘要数据
                SummaryFieldsData summaryFieldsData = new SummaryFieldsData();

                summaryFieldsData.setCardNo(jrno);
                summaryFieldsData.setDigest(digest);
                summaryFieldsData.setDigestFlag(digestFlag);
                summaryFieldsData.setEncryptFlag(encryptFlag);
                summaryFieldsDataList.add(summaryFieldsData);

                List<ICData> icDataList = new ArrayList<ICData>();
                ICData icd = new ICData();

                String cardNo = "";
                String cardNoFormat = "";
                String cvv = "";
                String expiry = "";
                String pbocDp = "";
                String track2 = "";
                String track1 = "";
                if ("0".equals(isSingleCard)) {// 单张制卡走报文形式//也要存储文件
                    icData = Data2[1];// 报文里的IC数据
                    pbocDp = ft.getPbocContent(icData, errors);
                    String[] cdData = cbsData.split("\\|");
                    cardNo = cdData[10];
                    cardNoFormat = cdData[10].substring(0, 6) + " **** **** "
                        + cdData[10].substring(cdData[10].length() - 4, cdData[10].length());
                    cvv = cdData[0] + " " + cdData[1];
                    expiry = cdData[9];
                    track2 = cdData[5];
                    track1 = branchCode;// 一磁 本次项目用于传输 申请机构

                    pwd.setCardNo(cardNo);
                    pwd.setCardNoFormat(cardNoFormat);
                    pwd.setCvv(cvv);
                    pwd.setExpiry(expiry);
                    pwd.setPbocDp(pbocDp);
                    pwd.setTrack2(track2);
                    pwd.setTrack1(track1);// 一磁 本次项目用于传输 申请机构
                    printWriteDataList.add(pwd);

                    /*--------------------2019年6月6日添加，用于校验卡面传送卡号、数据准备系统返回的磁条数据卡号、IC数据卡号，三号是否一致----------------------------*/
                    /*--------------------2019年6月6日添加，用于校验卡面传送卡号、数据准备系统返回的磁条数据卡号、IC数据卡号，三号是否一致----------------------------*/
                    /*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*//*Begin*/

                    // 使用指定的PBOC国密密钥解密 DGI0101中57Tag的等效二磁
                    // IC卡规范01：PBOC国际 02：VISA 03：MASTERCARD 04：PBOC国密

                    // List<String> ipList = new ArrayList();
                    // List<Integer> portList = new ArrayList();
                    // TUnionTransInfo transInfo = new TUnionTransInfo();
                    // UnionPbocKmsAPI shortApi = new UnionPbocKmsAPI(ipList, portList, 7, "QIS", "QIS");
                    // logger.info("PBOC30GMZEK--->"+PBOC30GMZEK);

                    String eqTrack2 = pbocDp.substring(60, 156);// IC数据中DGI0101中57Tag的等效二磁，用国密解密后获取卡号

                    String outData = "";// 363232393931313030373134363832353732443439313032323030303030303437343030314600000000000000000000
                    logger.info("eqTrack2--->" + eqTrack2);
                    outData = sClient.HsmServE161(encrypt_key, eqTrack2, null);
                    // eqTrack2例子//F36105CCA797A8AE2604843A0218678D426C6AA86AA64F24467A853ED387AF5C70D092A3DA9CCF7D9B4782E77CE31809
                    String ICCardNO = "";
                    String bcdOutData = "";

                    logger.debug("outData--->" + outData);
                    // bcdOutData = StringUtil.ASC2BCD(outData.getBytes());
                    logger.debug("bcdOutData--->" + outData);
                    ICCardNO = outData.substring(0, jrno.length());

                    if (cardNo.equals(ICCardNO) && cardNo.equals(jrno)) {
                        // 正常
                        logger.error("正常：三个卡号一致");
                        logger.info("磁条数据卡号--->" + cardNo);
                        logger.info("IC数据卡号--->" + ICCardNO);
                        logger.info("页面传送卡号--->" + jrno);
                    } else {
                        // 异常
                        logger.error("磁条数据卡号--->" + cardNo);
                        logger.error("IC数据卡号--->" + ICCardNO);
                        logger.error("页面传送卡号--->" + jrno);
                        resp.setErorcd("9999");
                        resp.setErortx("数据准备系统返回磁条数据和IC数据不一致！");
                        resp.setOriginalJson(JSON.toJSONString(dto));
                        packet.setBody(resp.toString());
                        session.write(packet.toString());
                        return;
                    }
                    /*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*//*END*/
                    /*--------------------2019年6月6日添加，用于校验卡面传送卡号、数据准备系统返回的磁条数据卡号、IC数据卡号，三号是否一致----------------------------*/
                    /*--------------------2019年6月6日添加，用于校验卡面传送卡号、数据准备系统返回的磁条数据卡号、IC数据卡号，三号是否一致----------------------------*/

                    icd.setCardNo(cardNo);
                    icd.setPbocDp(pbocDp);
                    icDataList.add(icd);
                    logger.info("--->解析ESB返回报文成功");
                    logger.info("--->开始通过FTS下载数据文件");

                    String sdf[] = cbsFile.split("/");
                    String sourceFile1 = "";// 磁条数据文件路径
                    String sourceFile2 = "";// IC数据文件路径
                    sourceFile1 = sdf[4] + "/" + sdf[5] + "/" + sdf[6];
                    String ssdf[] = icFile.split("/");
                    sourceFile2 = ssdf[4] + "/" + ssdf[5] + "/" + ssdf[6];
                    String destDir = "IC" + "/" + ssdf[5];
                    // 从IC核心系统通过ESB的FTS文件传输系统下载磁条数据文件和IC数据文件到服务器节点
                    String code =
                        jrkCardServer.sendFTSAndrecv(esb2, "AG_IC_01", sourceFile1, sourceFile2, "AG_QIS_01", destDir);
                    if ("000000".equals(code)) {
                        logger.info("--->FTS下载数据文件成功");
                    } else {
                        logger.warn("--->FTS下载数据文件失败");
                    }

                } else {// 批量制卡走数据解压入库形式
                        // 下载磁条文件和IC文件
                    // <cbsFile>/icappdata/fts/sndsplace/QIS/20171213/zhka_dfk_11109201_1600799999_20220502_37_002.txt</cbsFile>
                    // <icFile>/icappdata/fts/sndsplace/QIS/20171213/zhka_dfk_11109201_1600799999_20220502_37_002.zip</icFile>
                    logger.info("--->开始通过FTS下载数据文件");
                    String sdf[] = cbsFile.split("/");
                    String sourceFile1 = "";// 磁条数据文件路径
                    String sourceFile2 = "";// IC数据文件路径
                    sourceFile1 = sdf[4] + "/" + sdf[5] + "/" + sdf[6];
                    String ssdf[] = icFile.split("/");
                    sourceFile2 = ssdf[4] + "/" + ssdf[5] + "/" + ssdf[6];
                    String destDir = "IC" + "/" + ssdf[5];
                    // 从IC核心系统通过ESB的FTS文件传输系统下载磁条数据文件和IC数据文件到服务器节点
                    String code =
                        jrkCardServer.sendFTSAndrecv(esb2, "AG_IC_01", sourceFile1, sourceFile2, "AG_QIS_01", destDir);
                    if (!"000000".equals(code)) {
                        logger.error("--->FTS下载数据文件失败");
                        resp.setErorcd("9999");
                        resp.setErortx("下载数据文件出错");
                        resp.setOriginalJson(JSON.toJSONString(dto));
                        packet.setBody(resp.toString());
                        session.write(packet.toString());
                        return;
                    }
                    Param ftsDirParam = paramService.get("PKey", "ftsDir");
                    String recSourceFile1 = ftsDirParam.getPValue() + sdf[5] + "/" + sdf[6];// ServerConfigUtil.getValue("ftsDir")+sdf[5]+"/"+sdf[6];//接收到的磁条文件存入的本地路径
                    String recSourceFile2 = ftsDirParam.getPValue() + ssdf[5] + "/" + ssdf[6];// ServerConfigUtil.getValue("ftsDir")+ssdf[5]+"/"+ssdf[6];//接收到的IC文件存入的本地路径
                    String unZipSourceFile2 = recSourceFile2.replace(".zip", "");// 接收到的IC文件解压路径

                    if ("000000".equals(code)) {// 0表示文件传输成功
                        logger.info("--->FTS下载数据文件成功");
                        logger.info("--->开始解压文件并读取解析");
                        int totalLins = FileUtil.getTotalLines(recSourceFile1);// 读磁条文件，有几条数据就是几行
                        boolean isZip = ZipUtil.unZipFile(recSourceFile2, unZipSourceFile2);// 解压zip包，有几条数据解压后就有几个.bin文件
                        for (int i = 1; i <= totalLins; i++) {
                            String varContent = FileUtil.readLineVarFile(recSourceFile1, i);
                            cvv = varContent.substring(0, 4) + " " + varContent.substring(4, 36);
                            cardNo = varContent.substring(36, 54);
                            cardNoFormat = varContent.substring(36, 42) + " **** **** " + varContent.substring(50, 54);
                            expiry = varContent.substring(167, 199);
                            track2 = varContent.substring(59, 155);
                            track1 = varContent.substring(448, 458);

                            String binFileName = unZipSourceFile2 + "\\" + cardNo + ".bin";
                            // String binFileName = Base64Utils.validFilePath(unZipSourceFile2, "/");
                            // String base64Str = Base64Utils.fileToBase64(unZipSourceFile2, cardNo);
                            String base64Str = Base64Utils.fileToBase64(binFileName);
                            icData = CryptionUtil.bytesToHexString(Base64Utils.decode(base64Str));
                            pbocDp = ft.getPbocContent(icData, errors);

                            pwd.setCardNo(cardNo);
                            pwd.setCardNoFormat(cardNoFormat);
                            pwd.setCvv(cvv);
                            pwd.setExpiry(expiry);
                            pwd.setPbocDp(pbocDp);
                            pwd.setTrack2(track2);
                            pwd.setTrack1(track1);// 一磁 本次项目用于传输 申请机构
                            printWriteDataList.add(pwd);

                            icd.setCardNo(cardNo);
                            icd.setPbocDp(pbocDp);
                            icDataList.add(icd);

                            logger.info("--->解析数据文件完成");
                        }
                    }
                }

                PersoDatas data = new PersoDatas();
                data.setIcDataList(icDataList);
                data.setPrintWriteDataList(printWriteDataList);
                persoRecordService.savePersoDatas(data, branchCode, req.getIdtfno(), req.getCardpr(),
                    summaryFieldsDataList, cardSeqNo);// 摘要数据

                // dto = persoRecordService.findByIdNo(req.getIdtfno() , null , req.getCardpr());
                dto = persoRecordService.findByCardNo(cardNo, null);

            } else {
                resp.setErorcd("9999");
                resp.setErortx("未请求到制卡数据");
            }

            // PersoRecordDto dto2 = new PersoRecordDto();
            // dto2.setCardNo(cdData[10]);
            // dto2.setExpiry(cdData[9]);
            // dto2.setHoldName(cdData[1]);//页面显示信息，暂存CVV
            // dto2.setIdNumber("410423199001028888");
            // dto2.setPersoStatus("待制卡");
            // dto2.setPersoRecordId(1);
            resp.setOriginalJson(JSON.toJSONString(dto));
            packet.setBody(resp.toString());
            session.write(packet.toString());
            return;
        } catch (Exception ex) {
            logger.error(ex.toString());
            ex.printStackTrace();
            resp.setErorcd("9999");
            resp.setErortx("未知错误：" + ex.getMessage());
            resp.setOriginalJson("");
            packet.setBody(resp.toString());
            session.write(packet.toString());
        }

    }

    public boolean checkDigestByE180(String digest, String encryptFlag, String digestFlag, String encryKeyName,
        String digestKeyName, GetICDataResponse resp, SocketPacket packet, IoSession session, SketClient sClient,
        PersoRecordDto dto) {

        String checkResult;
        if (digest.length() != 439 && digest.length() != 343) {

            logger.warn("摘要字段长度不正确");
            resp.setErorcd("9999");
            resp.setErortx("摘要字段长度不正确");
            resp.setOriginalJson(JSON.toJSONString(dto));
            packet.setBody(resp.toString());
            session.write(packet.toString());
            return false;
        }
        String[] digestArray = digest.split("\\|");
        String hmac_sm3 = digestArray[7];

        String cvn2 = digestArray[0];// cvv
        String track2 = digestArray[1];// 二磁
        String expiry = digestArray[2];// 应用失效日期
        String effective = digestArray[3];// 应用生效日期
        String eqTrack2 = digestArray[4];// 等效二磁密文
        String pin = digestArray[5];
        String validDate = digestArray[6];
        String[] encryptData = {cvn2, track2, expiry, effective, eqTrack2, pin, validDate};
        String inputData = "";
        char[] encryptFlagArray = encryptFlag.toCharArray();
        char[] digestFlagArray = digestFlag.toCharArray();

        String digestData = "";
        String culDigestData = "";
        // 计算摘要
        if (digestFlag.equals(encryptFlag)) {
            // 解密cvn2、track2、expiry、effective、eqTrack2、pin、validDate
            if ("1111111".equals(encryptFlag)) {
                culDigestData =
                    cvn2 + "|" + track2 + "|" + expiry + "|" + effective + "|" + eqTrack2 + "|" + pin + "|" + validDate;
            } else if ("".equals(track2)) {
                culDigestData = cvn2 + "|" + expiry + "|" + effective + "|" + eqTrack2 + "|" + pin + "|" + validDate;
            } else {
                for (int i = 0; i < encryptFlagArray.length; i++) {
                    if ("1".equals(encryptFlagArray[i])) {
                        culDigestData += encryptData[i] + "|";
                    }
                }
            }
            System.out.println(culDigestData);
            // 解密返回字段直接传入加密平台验证摘要
            digestData = sClient.HsmServE161(encryKeyName, culDigestData, "|");
            digestData = digestData.replaceAll("\\|", "");
        } else {
            // 根据digestFlag确认验证摘要的字段
            // 拆分解密后的字段
            for (int i = 0; i < digestFlagArray.length; i++) {
                if ("1".equals(digestFlagArray[i])) {

                    if ("1".equals(encryptFlagArray[i])) {

                        // 先调用E161接口解密
                        String outData = sClient.HsmServE161(encryKeyName, encryptData[i], null);
                        digestData += outData;

                    } else {
                        digestData += encryptData[i];
                    }
                }
            }
        }
        // 调E180接口验证摘要
        if ("1".equals(sClient.HsmServE180(digestData, hmac_sm3, digestKeyName))) {
            System.out.println("摘要验证通过");
            logger.info("摘要验证通过");
            return true;
        } else {
            logger.info("摘要验证失败");
            resp.setErorcd("9999");
            resp.setErortx("摘要验证失败");
            resp.setOriginalJson(JSON.toJSONString(dto));
            packet.setBody(resp.toString());
            session.write(packet.toString());
            return false;
        }

    }

    public void decryptPrintData(PersoRecordDto dto, SketClient sketClient, String keyName) {

        // 解密时特殊处理cvv
        String[] cvvdata = dto.getCvv().split(" ");
        String printData = sketClient.HsmServE161(keyName, cvvdata[1] + "|" + dto.getExpiry(), "|");

        String[] data = printData.split("\\|");
        dto.setCvv(cvvdata[0] + " " + data[0]);
        dto.setExpiry(data[1]);
    }

    /*@Override
    public void handle(IoSession session, SocketPacket packet) throws Exception {
       
        PersoRecordDto dto = new PersoRecordDto();
        GetICDataResponse resp = new GetICDataResponse();
        FileTouch ft = new FileTouch();
        Errors errors = new Errors();
        try {
            // 从数据库中查询，是否存存当前证件号数据
            IPersoRecordService persoRecordService = ServiceManager.getManager().getBean("persoRecordServiceImpl", PersoRecordServiceImpl.class);
            ILogPersoRecevieService lprService = ServiceManager.getManager().getBean("logPersoRecevieServiceImpl", LogPersoRecevieServiceImpl.class);
            GetICDataRequest req = new GetICDataRequest(packet.getBody());
            dto = persoRecordService.findByIdNo(req.getIdtfno() , null , req.getCardpr());
            if (dto != null) {
                resp.setOriginalJson(JSON.toJSONString(dto));
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            dto = persoRecordService.findByIdNo(req.getIdtfno() ,Global.PERSO_CODE_PRINTING , req.getCardpr());
            //如果制卡状态为制卡中
            if(dto != null ){
                resp.setErorcd("9999");
                resp.setErortx("当前数据制卡状态为【制卡中】,如需重新制卡，请使用【数据重置】功能。");
                resp.setOriginalJson("");
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            
            
            // 1.从IC卡系统获取数据批次号
            JRKCardServer jrkCardServer = new JRKCardServer();
            errors = new Errors();
            String batchNo = jrkCardServer.applyData(req , errors);
            if(errors.hasErrors()){
                resp.setErorcd("9999");
                resp.setErortx(errors.getAllErrors().get(0).getMessage());
                resp.setOriginalJson("");
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            String trantm  = DateUtil.timestampToString(DateUtil.nowTimestamp(), "YYYYMMdd");
    //            batchNo = "000000000000000086";
    //            trantm = "20170703";
            // 2.从FTP下载数据
            errors = new Errors();
            FtpPlugin plugin = new FtpPlugin();
            String fileName =  plugin.downloadFile(batchNo, trantm , errors);
            if(StringUtils.isBlank(fileName) || fileName == null){
                resp.setErorcd("9999");
                resp.setErortx(errors.getAllErrors().get(0).getMessage());
                resp.setOriginalJson("");
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            System.out.println(fileName);
            //2.从数据库中校验当前文件名是否存在
            String fn = fileName.replaceAll(".zip", "").replaceAll(".ZIP", "");
            LogPersoRecevie lpr = lprService.findByFileName(fn);
            if(lpr != null){
                resp.setErorcd("9999");
                resp.setErortx("请不要重复请求数据.当前文件[ "+ fn +" ] 已导入.");
                resp.setOriginalJson("");
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            
            errors = new Errors();
            // 3.从本地目录解析制卡数据
            File file = new File("./tmp/"+trantm , fileName);
            PersoDatas datas = ft.analysis(file, errors);
            if (errors.hasErrors()) {
                resp.setErorcd("9999");
                resp.setErortx(errors.getAllErrors().get(0).getMessage());
                resp.setOriginalJson("");
                packet.setBody(resp.toString());
                session.write(packet.toString());
                return;
            }
            
            // 4.保存入库
            if (datas != null) {
                persoRecordService.savePersoDatas(datas , req.getBranchCode() , req.getIdtfno() , req.getCardpr());
            }
            //删除数据文件
            FileUtil.deleteDirectory(new File("./tmp/"+trantm));
            // 5.返回数据信息
            dto = persoRecordService.findByIdNo(req.getIdtfno() , null , req.getCardpr());
            if(dto != null){
                //将当前文件名入库
                lprService.saveRersoRecevieLog("", fn);
            }
            resp.setOriginalJson(JSON.toJSONString(dto));
            packet.setBody(resp.toString());
            session.write(packet.toString());
            return;
        } catch (Exception ex) {
            ex.printStackTrace();
            resp.setErorcd("9999");
            resp.setErortx("未知错误：" + ex.getMessage());
            resp.setOriginalJson("");
            packet.setBody(resp.toString());
            session.write(packet.toString());
        }
       
    }*/
}
